// 原型链继承
function Animal() {
  this.colors = ['black', 'white']
}
Animal.prototype.getColor = function() {
  return this.colors
}
function Dog() {}
Dog.prototype =  new Animal()

// 原型链继承存在的问题：
// 问题1：原型中包含的引用类型属性将被所有实例共享；
// 问题2：子类在实例化的时候不能给父类构造函数传参；

// 借用构造函数实现继承
function Animal(name) {
  this.name = name
  this.getName = function() {
      return this.name
  }
}
function Dog(name) {
  Animal.call(this, name)
}
Dog.prototype =  new Animal()
// 借用构造函数实现继承解决了原型链继承的 2 个问题：
// 引用类型共享问题以及传参问题。
// 但是由于方法必须定义在构造函数中，所以会导致每次创建子类实例都会创建一遍方法。

// 组合继承
function Animal(name) {
  this.name = name
  this.colors = ['black', 'white']
}
Animal.prototype.getName = function() {
  return this.name
}
function Dog(name, age) {
  Animal.call(this, name)
  this.age = age
}
Dog.prototype =  new Animal()
Dog.prototype.constructor = Dog

//class 相当于es5中构造函数
//class中定义方法时，前后不能加function，全部定义在class的protopyte属性中
//class中定义的所有方法是不可枚举的
//class中只能定义方法，不能定义对象，变量等
//class和方法内默认都是严格模式
//es5中constructor为隐式属性
class People{
    constructor(name='wang',age='27'){
      this.name = name;
      this.age = age;
    }
    eat(){
      console.log(`${this.name} ${this.age} eat food`)
    }
  }
  //继承父类
  class Woman extends People{ 
     constructor(name = 'ren',age = '27'){ 
       //继承父类属性
       super(name, age); 
     } 
      eat(){ 
       //继承父类方法
        super.eat() 
      } 
  } 
  let wonmanObj=new Woman('xiaoxiami'); 
  wonmanObj.eat();
   
  //es5继承先创建子类的实例对象，然后再将父类的方法添加到this上（Parent.apply(this)）。 
  //es6继承是使用关键字super先创建父类的实例对象this，最后在子类class中修改this。